package xyz.ibenben.zhongdian.common.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.*;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.*;
import org.apache.shiro.util.ByteSource;
import xyz.ibenben.zhongdian.common.constants.Constants;
import xyz.ibenben.zhongdian.system.entity.sys.*;
import xyz.ibenben.zhongdian.system.service.sys.*;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author chenjian
 * @since 2017年10月18日下午5:17:22
 */
public class MyShiroRealm extends AuthorizingRealm {
	@Resource
	private SysUserService sysUserService;

	@Resource
	private SysResourcesService sysResourcesService;
	
	/**
	 * 授权
	 * @param principalCollection 参数
	 * @return 返回值
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();
		//User的格式为 id=1, username=admin, password=3ef7164d1f6167cb9f2658c07d3c2f0a, enable=1
		
		List<SysResources> resourcesList = sysResourcesService.loadUserResources(user.getId());
		// 权限信息对象info,用来存放查出的用户的所有的角色（sysRole）及权限（permission）
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		for(SysResources resources: resourcesList){
			if(null != resources.getResUrl()){
				info.addStringPermission(resources.getResUrl());
			}
		}
		return info;
	}

	/**
	 * 认证
	 * @param token 参数
	 * @return 返回值
	 * @throws AuthenticationException 异常
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		//获取用户的输入的账号.
		String username = (String)token.getPrincipal();
		SysUser user = sysUserService.selectByUsername(username);
		if(user == null){
			throw new UnknownAccountException();
		}
		if (0 == user.getEnable()) {
			throw new LockedAccountException(); // 帐号锁定
		}
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
				user, //用户
				user.getPassword(), //密码
				ByteSource.Util.bytes(username),
				getName()  //realm name
		);
		// 当验证都通过后，把用户信息放在session里
		Session session = SecurityUtils.getSubject().getSession();
		session.setAttribute(Constants.SESSION, user);
		session.setAttribute(Constants.SESSIONID, user.getId());
		return authenticationInfo;
	}

	/**
	 * 指定principalCollection 清除
	 * @param principalCollection 参数
	 */
	public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(
				principalCollection, getName());
		super.clearCachedAuthorizationInfo(principals);
	}

}
